package nl.tue.bsdddump;

import java.io.BufferedWriter;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.NewCookie;

import org.apache.log4j.Logger;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.jaxrs.JacksonJsonProvider;
import org.codehaus.jackson.map.ObjectMapper;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.json.JSONConfiguration;

import no.catenda.peregrine.model.objects.json.IfdConcept;


public class PeregrineConceptSearchCallable implements Callable{

	private String searchTerm ="";
	private ConceptSearchQueryResult result;


	private static List<NewCookie> cookies;
	private static Logger logger = Logger.getLogger(PeregrineConceptSearchCallable.class);
	private static String searchURL = "http://bsddpilot.catenda.no/api/4.0/IfdConcept/search/";
	
	
	public PeregrineConceptSearchCallable ( String searchTerm, List<NewCookie>cookies){
		this.searchTerm=searchTerm;
		this.cookies = cookies;
	}
	
	
	public ConceptSearchQueryResult call() throws Exception {
		String res = "";
		try {
			//System.out.println("searching "+searchTerm);
			ClientConfig clientConfig = new DefaultClientConfig();
			clientConfig.getClasses().add(JacksonJsonProvider.class);
			clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
			Client client = Client.create(clientConfig);
			String s= URLEncoder.encode("*","UTF-8");

				
			
			WebResource searchCall = client.resource(searchURL+searchTerm+s);
			//Thread.sleep(1000);
			res =  searchCall.accept(MediaType.APPLICATION_JSON_TYPE).cookie(cookies.get(0)).get(String.class);
			
			if (res.equalsIgnoreCase("null")==false){
				ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY);

				mapper.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
				mapper.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
				JsonNode root = mapper.readTree(res);
				
				JsonNode jsonConcepts = root.get("IfdConcept");

				//System.out.println("search "+searchTerm+" answers is array: "+jsonConcepts.isArray());
				
				ConceptSearchQueryResult csqr = new ConceptSearchQueryResult();
				HashSet<IfdConcept> concepts = new HashSet<IfdConcept>();
				if (jsonConcepts.isArray()){
				Iterator<JsonNode> iterator = jsonConcepts.iterator();
				while (iterator.hasNext()) {
					JsonNode jsonNode = (JsonNode) iterator.next();
					IfdConcept c = mapper.readValue(jsonNode,IfdConcept.class);
					concepts.add(c);

				}
				}
				else {
					IfdConcept c = mapper.readValue(jsonConcepts,IfdConcept.class);
					concepts.add(c);
				}
				csqr.setSearchResult(concepts);
				csqr.setSearchTerm(searchTerm);
//				csqr.setTimestamp()
				
				return csqr;

			}
			else{
				//unreachable? should throw an exception before
				//System.err.println("searchCall anserwer for "+searchTerm+" was "+res);
				ConceptSearchQueryResult csqr = new ConceptSearchQueryResult();
				csqr.setSearchTerm(searchTerm);
				return csqr;
				
			}
		} catch (Exception e) {
			logger.error(e.getStackTrace()[0]);
			logger.error("answer was "+res);
			System.err.println("exeption for "+searchTerm);
			e.printStackTrace();
			throw new ConceptSearchException(searchTerm);
		}

	}

	public String getSearchTerm() {
		return searchTerm;
	}


	public void setSearchTerm(String searchTerm) {
		this.searchTerm = searchTerm;
	}
	

}
